package strcy.cn.market.service.Impl;


import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import strcy.cn.market.pojo.Mail;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class MailService {

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private StringRedisTemplate redisTemplate; // Redis

    @Value("${spring.mail.username}")
    private String username;

    private static final String CODE_PREFIX = "email_code:"; // Redis key 前缀

    /**
     * 发送普通文本
     * @param mail 邮件类
     * @return
     * @throws MessagingException
     */
    public Boolean sendTextMail(Mail mail) throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage(); //创建一个 MimeMessage 对象,表示一封邮件
        MimeMessageHelper helper = new MimeMessageHelper(message, false); // 第二个参数 false 表示纯文本
        helper.setFrom(username);
        helper.setTo(mail.getTo());
        helper.setSubject(mail.getSubject());
        helper.setText(mail.getContent(), false);
        mailSender.send(message);
        return true;
    }

    /**
     * 发送HTML
     * @param mail 邮件类
     * @return
     * @throws MessagingException
     */
    public Boolean sendHtmlMail(Mail mail) throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);// 允许HTML
        helper.setFrom(username);
        helper.setTo(mail.getTo());
        helper.setSubject(mail.getSubject());
        helper.setText("", true);// 第二个参数 true 表示 HTML
        mailSender.send(message);
        return true;
    }

    /**
     * 发送附件
     * @param mail 邮件
     * @return
     * @throws MessagingException,FileNotFoundException
     */
    public Boolean sendAttachmentMail(Mail mail) throws MessagingException, FileNotFoundException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(username);
        helper.setTo(mail.getTo());
        helper.setSubject(mail.getSubject());
        helper.setText(mail.getContent(),false);

        // 获取附件路径
        String attachmentPath = mail.getAttachment();

        // 创建 File 对象并检查是否存在
        File file = new File(attachmentPath);
        if (!file.exists()) {
            throw new FileNotFoundException("附件文件未找到: " + attachmentPath);
        }

        // 创建 FileSystemResource Spring 用于读取文件的封装类，可以用来处理附件。
        FileSystemResource resource = new FileSystemResource(file);

        // 添加附件 file.getName()文件名 resource 文件资源
        helper.addAttachment(file.getName(), resource);
        mailSender.send(message);
        return true;
    }


    /**
     * 发送图片
     * @param mail 邮件
     * @return
     * @throws MessagingException
     * @throws FileNotFoundException
     */
    public Boolean sendPictureMail(Mail mail) throws MessagingException, FileNotFoundException {
        // 创建 MimeMessage 和 MimeMessageHelper 对象
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);

        // 获取图片路径
        String picturePath = mail.getAttachment();

        // 检查图片路径是否为空
        if (picturePath == null || picturePath.trim().isEmpty()) {
            throw new IllegalArgumentException("图片路径不能为空");
        }

        // 创建 File 对象并检查是否存在
        File file = new File(picturePath);
        if (!file.exists()) {
            throw new FileNotFoundException("附件文件未找到图片: " + picturePath);
        }
        // 设置邮件的发件人、收件人、主题和内容
        helper.setFrom(username);
        helper.setTo(mail.getTo());
        helper.setSubject(mail.getSubject());
        helper.setText("<p>这是一封带图片的邮件：</p><img src='cid:" + file.getName() + "'/>", true);  // true 表示 HTML 内容

        // 如果文件存在，添加内嵌图片
        FileSystemResource res = new FileSystemResource(file);
        // 添加图片，确保图片名是唯一且正确的
        helper.addInline(file.getName(), res);  // 使用文件名作为 cid

        // 发送邮件
        mailSender.send(message);
        return true;
    }

    /**
     * 发送验证码
     * @param to 请求邮箱地址
     * @throws MessagingException
     */
    public void sendVerificationCode(String to) throws MessagingException {
        String code = generateCode(); // 生成 6 位验证码

        // 存入 Redis，2 分钟有效 将验证码存储在 Redis 中，键名是 CODE_PREFIX + to，即基于邮箱地址作为唯一标识。
        redisTemplate.opsForValue().set(CODE_PREFIX + to, code, 5, TimeUnit.MINUTES);

        Mail mail = new Mail();
        // 发送邮件
        mail.setTo(to);
        mail.setSubject("会议管理系统注册验证码");
        mail.setContent("您的验证码是：" + code + "，有效期 5 分钟，请勿泄露。");
        sendTextMail(mail);
    }

    // 生成 6 位随机验证码
    private String generateCode() {
        return String.valueOf(new Random().nextInt(899999) + 100000);
    }

    //验证验证码
    public boolean verifyCode(String to, String code) {
        //从 Redis 中获取指定邮箱对应的验证码。如果 Redis 中没有找到该验证码，说明验证码已经过期或不存在。
        String redisCode = redisTemplate.opsForValue().get(CODE_PREFIX + to);
        //如果 redisCode 为 null，则表示验证码已经过期或未生成，方法返回 false，表示验证码验证失败。
        if (redisCode == null) {
            return false; // 验证码已过期
        }
        //如果 Redis 中存在验证码，接下来就与用户传入的验证码进行比较。如果两者相等，则返回 true，表示验证码验证成功，否则返回 false。
        return redisCode.equals(code);
    }
}
